package org.irri.smta.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileUtils {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(FileUtils.class);

	public static String getTextFileContents(File file) {
		StringBuilder contents = new StringBuilder();

		try {
			// use buffering, reading one line at a time
			// FileReader always assumes default encoding is OK!
			BufferedReader input = new BufferedReader(new FileReader(file));
			try {
				String line = null; // not declared within while loop
				/*
				 * readLine is a bit quirky : it returns the content of a line
				 * MINUS the newline. it returns null only for the END of the
				 * stream. it returns an empty String if two newlines appear in
				 * a row.
				 */
				while ((line = input.readLine()) != null) {
					contents.append(line);
					contents.append(System.getProperty("line.separator"));
				}
			} finally {
				input.close();
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		return contents.toString();
	}

	public static byte[] fileToByteArray(File file) throws Exception {
		InputStream is = new FileInputStream(file);

		// Get the size of the file
		long length = file.length();

		// You cannot create an array using a long type, so it needs to be an
		// integer type.
		// Before converting to an integer type, check to ensure that file is
		// not larger than Integer.MAX_VALUE.
		if (length > Integer.MAX_VALUE) {
			is.close();
			LOGGER.error("File is too large!");
			throw new Exception("File is too large!");
		}

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) length];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			is.close();
			throw new IOException("Could not completely read file "
					+ file.getName());
		}
		// Close the input stream and return bytes
		is.close();

		return bytes;
	}

	public static Boolean downloadFile(String urlString, File localFile) {
		try {
			// Get a connection to the URL and start up a buffered reader.
			long startTime = System.currentTimeMillis();

			LOGGER.info("Connecting to URL: " + urlString);

			URL url = new URL(urlString);
			url.openConnection();
			InputStream reader = url.openStream();

			// Setup a buffered file writer to write out what we read from the
			// site.

			FileOutputStream writer = new FileOutputStream(localFile);
			byte[] buffer = new byte[153600];
			int totalBytesRead = 0;
			int bytesRead = 0;

			LOGGER.info("Reading file 150KB blocks at a time.");

			while ((bytesRead = reader.read(buffer)) > 0) {
				writer.write(buffer, 0, bytesRead);
				buffer = new byte[153600];
				totalBytesRead += bytesRead;
			}

			long endTime = System.currentTimeMillis();

			LOGGER.info("Done. " + (new Integer(totalBytesRead).toString())
					+ " bytes read ("
					+ (new Long(endTime - startTime).toString())
					+ " millseconds).\n");

			writer.close();
			reader.close();

			return true;
		} catch (MalformedURLException e) {
			LOGGER.error(e.getMessage());
		} catch (IOException e) {
			LOGGER.error(e.getMessage());
		}

		return false;
	}

}
